<template>  
	<Form
		# 		= '{ form }'
		ref 	= 'formRef' 
		class 	= 'jzer-form jzer-submit-form'
		:class 	= "[isScroll ? 'fv abs_full':'', `jzer-form-${config.size}`, config.labelWidth]" 
		@submit = 'onSubmit'
		@init 	= 'onInit'
	>
		<div :class="{'ex oys scrollbar': isScroll}" :style="{padding: isScroll?'15px 10px':0 }">
			<div class='fxw' :key='key'>
				<SubmitItemComponent :data='config.data' :form='form' :loading='loading || ajax.loading' :config='config' :ajax='ajax' :mb='mb' :formRef='formRef' :submitRef='f' :edit='edit'>
					<template v-for="(v,i) in (config.data ?? []).filter(v => v.type === 'slot')" :key='i' #[v.name]='{ f, n, disabled, readOnly, data }'>
						<slot :name='v.name' :n='n' :f='f' :disabled='disabled' :readOnly='readOnly' :data='data' :loading='loading || ajax.loading'></slot>
					</template>
				</SubmitItemComponent>
				<slot></slot>
			</div>
			<Loading :loading='loading || ajax.loading' />
		</div>
		<footer :class="[ isScroll?'tbor1 pt10' :'', controls?.align === 'center' ? 'fxmc p10' : 'fxm pb10' ]" v-if='controls !== false'>
			<div v-if="controls?.align === 'start'" class='ant-form-item-label' style='margin:0 10px 0 0!important;'></div>
			<Controls :align="controls?.align" :size="controls?.size" :loading='loading || ajax.loading' :config='{ controls: btnData }' />
		</footer>
	</Form>
</template>

<script setup>
	import { watch, onMounted, h } from 'vue'
	import Form from '@antd/form/layout/form.vue'
	import SubmitItemComponent from './item/submit-item.vue'
	import SubmitUtils from '#cpt/utils/submit'
	import { useRouter } from 'vue-router'
	const router = useRouter()
	/* --------------------------- Component --------------------------- */
	// const Form 			= $.lazy(()=>import('@antd/form/layout/form.vue'))
	const Controls 	= $.lazy(()=>import('#cpt/temp/Controls.vue'))
	const Loading = $.lazy(()=>import('@antd/loading.vue'))
	/* --------------------------- props --------------------------- */
	const props = defineProps({
		loading 	: [Boolean, Number],
		width		: { type:String, default: '100%' },
		labelWidth	: { type:String, default: 's4' },
		mb 			: { type:Number, default: 20 },
		config 		: { type:Object, default: { data:[] } },
		scroll 		: [Boolean, Number],
		controls  	: { type:[ Object, Array, Boolean, Function ], default: ({ config }) => config.controls ?? {} },
		cache 		: { type:[Boolean, Number], default: ({ config }) => config.cache ?? $config.cache },
		isSubmitForm : { type:[Boolean, Number], default: true }
	})
	const { width, api, cache, loading, scroll, isSubmitForm } = props
	
	const fn = $fn
	let formRef = $ref()
	let ajax = $ref({})
	let key = $ref(0)
	let edit = $ref()
	let config = $ref({
		size 		: 'submit',
		edit 		: 0,
		...props.config,
		data 		: $fn.getResult( props?.config?.data, { formRef } )
	})
	let isScroll = $ref(scroll || config.scroll)
	/* --------------------------- Emit --------------------------- */
	const emit = defineEmits(['init', 'submit', 'cancel', 'ok'])
	const onSubmit = param => {
		param = { ...param, ...formRef.getForm() }
		if( isSubmitForm ){
			SubmitUtils({ isSubmitForm, ajax, param, submitConfig:config, emit, formRef })
		}else{
			emit('submit', { param, formRef } )
		}
	}
	/* ---------------------------  --------------------------- */
	const reset = name => formRef.reset(name)
	
	// 表单提交回显赋值
	const setBackInfo = () => {
		let { onBackData, backData, infoApi, api, id, idStr, backParam, abs, onAdd, onEnd, mode } = config
		backParam = $fn.getResult(backParam)	// 回显参数
		infoApi = infoApi || api
		if( mode === 'add'){ return onAdd?.() }
		
		if( id || mode === 'mod' ){
			id = $fn.getResult(id)
			if( !abs ){ backParam = { [idStr]: id, ...backParam } }
			id = backParam ? null : id
			if(props.infoApi !== false || props.infoApi !== 0){
				$http.pull(ajax, infoApi, { id, param:backParam }).then(data=>{
					const p = {data, formRef}
					if( onBackData ){
						onBackData?.( p )
					}else{
						backData = $fn.getResult(backData, p)
						formRef?.setBackValue?.(config.data, {...data,...backData})
					}
					onEnd?.(p)
				})
			}else{
				const sendParam = { config, formRef }
				// 本地数据回显
				backData ? formRef?.setBackValue?.( $fn.getResult(backData, sendParam) ) : onBackData?.(sendParam)
				onEnd?.(sendParam)
			}
		}
	}
	
	//
	onMounted(()=>{
		if( isSubmitForm ) setBackInfo()
	})
	
	/* --------------------------- 暴露方法 --------------------------- */
	const f = {
		// 提交表单
		submit: () => formRef.submit(),
		// 重置表单
		reset,
		resetValue: name => formRef.resetValue(name),
		// 回显值
		setValues: value => formRef.setValues(value),
		setValue: (value, bool) => formRef.setValue(value, bool),
		setDefaultValue: (data, bool) => formRef.setDefaultValue(data, bool),
		// 表单提交回显赋值
		setBackValue: (value,bool) => formRef.setBackValue(config.data, value, bool),
		// 获取表单字段值
		getValue: name => formRef.getValue(name),
		getName: name => formRef.getName(name),
		// 动态设置表单数据
		data: data => {
			if(arguments.length === 0){
				return config.data
			}else{
				config.data = data
			}
		},
		setBackInfo,
		getRef : () => formRef,
		SubmitUtils
	}
	/* --------------------------- controls --------------------------- */
	let controls  = $ref( props.controls )
	let btnData = $ref( [] )
	const setControls = () => {
		controls = $fn.getResult(controls,{ f,formRef })
		if( $fn.hasArray( controls ) ){
			btnData = controls
		}else if( $fn.isObject( controls ) ){
			controls.align = controls.align ?? 'center'
			controls.size = controls.size ?? 'middle'
			const { ok, back, reset,  before=[], after=[] } = controls
			btnData = [
				...before,
				{type:'default', mode:'back', click:()=> {
					const bool = controls?.onBack?.(formRef)
					if( bool !== false ){
						$fn.back()
					}
				}, ...back},
				{label:'重置', ghost:true, click:()=> {
					formRef.reset()
					controls?.onReset?.()
				}, ...reset },
				{label:'确定', htmlType:'submit',  ...ok },
				...after,
			]
		}
	}
	if(controls != false ){ setControls(controls) }
	// watch(()=>props.controls, value=>setControls(value))
	/* --------------------------- 初始化 --------------------------- */
	const onInit = ({ form}) => {
		let { param } = config
		// 配置默认参数
		param = $fn.getResult(param)
		// 从 value 配置默认参数
		formRef.setDefaultValue( config.data, param )
		
		const p = { formRef:f, param, form }
		
		config.data = $fn.getResult( props?.config?.data, p )
		
		if(isSubmitForm){
			config?.onInit?.( p )
		}
		emit('init', p)
	}
	/* --------------------------- 通信 --------------------------- */
	defineExpose(f)
</script>